package com.chinda.modules.job.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinda.common.enums.ScheduleStatusEnum;
import com.chinda.common.page.RPage;
import com.chinda.modules.job.dao.ScheduleJobDao;
import com.chinda.modules.job.entity.ScheduleJobEntity;
import com.chinda.modules.job.qo.ScheduleJobQO;
import com.chinda.modules.job.service.ScheduleJobService;
import com.chinda.modules.job.utils.ScheduleUtils;
import lombok.AllArgsConstructor;
import org.quartz.Scheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 定时任务
 *
 * @author chinda
 * @date 2021-07-09 19:09:10
 */
@AllArgsConstructor
@Service("scheduleJobService")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobDao, ScheduleJobEntity> implements ScheduleJobService {

    private final Scheduler scheduler;

    /**
     * 获取分页信息
     *
     * @param qo
     * @return
     */
    @Override
    public RPage page(ScheduleJobQO qo) {
        return new RPage(page(qo.getPage(), qo.getQueryWrapper()));
    }

    /**
     * 保存定时任务
     *
     * @param scheduleJob
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveJob(ScheduleJobEntity scheduleJob) {
        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
        scheduleJob.setStatus(ScheduleStatusEnum.NORMAL);
        save(scheduleJob);
    }

    /**
     * 更新定时任务
     *
     * @param scheduleJob
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateJob(ScheduleJobEntity scheduleJob) {
        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
        return updateById(scheduleJob);
    }

    /**
     * 删除定时任务
     *
     * @param jobId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long jobId) {
        ScheduleUtils.deleteScheduleJob(scheduler, jobId);
        removeById(jobId);
    }

    /**
     * 批量删除定时任务
     *
     * @param idList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Long> idList) {
        for(Long jobId : idList){
            ScheduleUtils.deleteScheduleJob(scheduler, jobId);
        }
        removeByIds(idList);
    }

    /**
     * 立即执行
     *
     * @param jobIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(Long[] jobIds) {
        for(Long jobId : jobIds){
            ScheduleUtils.run(scheduler, this.getById(jobId));
        }
    }

    /**
     * 暂停运行
     *
     * @param jobIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pause(Long[] jobIds) {
        for(Long jobId : jobIds){
            ScheduleUtils.pauseJob(scheduler, jobId);
        }
        updateBatch(jobIds, ScheduleStatusEnum.PAUSE);
    }

    /**
     * 恢复运行
     *
     * @param jobIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resume(Long[] jobIds) {
        for(Long jobId : jobIds){
            ScheduleUtils.resumeJob(scheduler, jobId);
        }
        updateBatch(jobIds, ScheduleStatusEnum.NORMAL);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBatch(Long[] jobIds, ScheduleStatusEnum status) {
        List<ScheduleJobEntity> scheduleJobList = baseMapper.selectBatchIds(Arrays.asList(jobIds)).stream()
                .map(job -> {
                    job.setStatus(status);
                    return job;
                })
                .collect(Collectors.toList());
        return saveOrUpdateBatch(scheduleJobList);
    }
}